package thread;
/**
 * 线程并发安全问题
 * 同步块:
 *  synchronized(同步监视器对象){
 *      需要多个线程同时执行的代码
 *  }
 */
public class SyncDemo1 {
    public static void main(String[] args) {
        Shop shop =new Shop();
        Thread t1 =new Thread("wkj"){
            public void run(){
                shop.buy();
            }
        };

        Thread t2 =new Thread("wj"){
            public void run(){
                shop.buy();
            }
        };
        t1.start();
        t2.start();

        //区分abc和this
//        Shop shop1 =new Shop();
//        Shop shop2 =new Shop();
//        /*Thread t1 =new Thread("wkj"){
//            public void run(){
//                shop1.buy();
//            }
//        };*/
//        Thread t1 =new Thread(shop1::buy);
//
//        Thread t2 =new Thread("wj"){
//            public void run(){
//                shop2.buy();
//            }
//        };
//        //下面那里如果是  //synchronized ("abc") 那就不能同时试衣服 虽然逛的是两个不同商店 但abc锁的是同一个 所以不要用abc
//        t1.start();
//        t2.start();

    }
}
 class Shop{
    //public synchronized void buy(){//在方法上同步监视(加锁)，范围比较大,同步监视对象只能是this
    public void buy(){
        try {
            Thread t = Thread.currentThread();//获取的是调用buy方法的线程
            System.out.println(t.getName()+"正在挑衣服");
            Thread.sleep(3000);
            /*
            同步监视对象通常使用:临界资源
            临界资源:抢谁谁就是临界资源，说白了，抢谁就锁谁
             */
            synchronized (this){ //同步监视块，缩小了监视范围 谁调用方法 谁就是this ，锁的是shop 临界资源 抢谁锁谁
                //只要是同一个对象，就一定会被锁住，同一家商店可以锁住，不同商店就不锁
            //synchronized (new Object()){//永远不能用实例化的对象作为同步监视器对象，一定无效
            //synchronized (123){ //同步监视器对象一定是一个引用类型
            //synchronized ("abc"){//锁的是abc，同一个对象，虽然可以，但abc并不是合适的对象，abc存在常量池中，wkj直接引用，wj会复用地址


                System.out.println(t.getName()+"正在试衣服");
                Thread.sleep(3000);
            }
            System.out.println(t.getName()+"结账离开");
        } catch (InterruptedException e) {
            e.printStackTrace();

        }
    }
 }
